Index: sys/filedesc.h
===================================================================
RCS file: /base/FreeBSD-CVS/src/sys/sys/filedesc.h,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 filedesc.h
--- filedesc.h	1999/08/29 16:32:22	1.15.2.1
+++ filedesc.h	2000/01/20 21:39:29
@@ -139,6 +139,7 @@
 int	fsetown __P((pid_t, struct sigio **));
 void	funsetown __P((struct sigio *));
 void	funsetownlst __P((struct sigiolst *));
+void	setugidsafety __P((struct proc *p));
 #endif
 
 #endif
Index: kern/kern_descrip.c
===================================================================
RCS file: /base/FreeBSD-CVS/src/sys/kern/kern_descrip.c,v
retrieving revision 1.58.2.3
diff -u -r1.58.2.3 kern_descrip.c
--- kern_descrip.c	1999/11/18 08:09:08	1.58.2.3
+++ kern_descrip.c	2000/01/20 21:40:00
@@ -984,6 +984,62 @@
 }
 
 /*
+ * For setuid/setgid programs we don't want to people to use that setuidness
+ * to generate error messages which write to a file which otherwise would
+ * otherwise be off limits to the proces.
+ *
+ * This is a gross hack to plug the hole.  A better solution would involve
+ * a special vop or other form of generalized access control mechanism.  We
+ * go ahead and just reject all procfs file systems accesses as dangerous.
+ *
+ * Since setugidsafety calls this only for fd 0, 1 and 2, this check is
+ * sufficient.  We also don't for setugidness since we know we are.
+ */
+static int
+is_unsafe(struct file *fp)
+{
+	if (fp->f_type == DTYPE_VNODE && 
+	    ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS)
+		return (1);
+	return (0);
+}
+
+/*
+ * Make this setguid thing safe, if at all possible.
+ */
+void
+setugidsafety(p)
+	struct proc *p;
+{
+	struct filedesc *fdp = p->p_fd;
+	struct file **fpp;
+	char *fdfp;
+	register int i;
+
+	/* Certain daemons might not have file descriptors. */
+	if (fdp == NULL)
+		return;
+
+	fpp = fdp->fd_ofiles;
+	fdfp = fdp->fd_ofileflags;
+	for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) {
+		if (i > 2)
+			break;
+		if (*fpp != NULL && is_unsafe(*fpp)) {
+			if (*fdfp & UF_MAPPED)
+				(void) munmapfd(p, i);
+			(void) closef(*fpp, p);
+			*fpp = NULL;
+			*fdfp = 0;
+			if (i < fdp->fd_freefile)
+				fdp->fd_freefile = i;
+		}
+	}
+	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
+		fdp->fd_lastfile--;
+}
+
+/*
  * Close any files on exec?
  */
 void
Index: kern/kern_exec.c
===================================================================
RCS file: /base/FreeBSD-CVS/src/sys/kern/kern_exec.c,v
retrieving revision 1.93.2.3
diff -u -r1.93.2.3 kern_exec.c
--- kern_exec.c	1999/08/29 16:25:58	1.93.2.3
+++ kern_exec.c	2000/01/20 21:39:29
@@ -281,6 +281,7 @@
 		if (attr.va_mode & VSGID)
 			p->p_ucred->cr_gid = attr.va_gid;
 		setsugid(p);
+		setugidsafety(p);
 	} else {
 		if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
 		    p->p_ucred->cr_gid == p->p_cred->p_rgid)
